#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
from typing import List, Dict, Any


# 字数统计
def count_words(text: str, word_compatible: bool = False) -> int:
    """
    统计文本中的字数，支持通用模式和Word兼容模式
    
    Args:
        text (str): 需要统计的文本
        word_compatible (bool): 是否使用Word兼容模式，适用于学术文献
        
    Returns:
        int: 文本总字数
        
    Examples:
        >>> count_words("Hello世界")  # 通用模式
        3
        >>> count_words("Hello世界", word_compatible=True)  # Word兼容模式
        7
    """
    if not text:
        return 0
    
    if word_compatible:
        return _count_words_word_compatible(text)
    else:
        return _count_words_general(text)


def _count_words_general(text: str) -> int:
    """
    通用模式字数统计
    
    规则：
    - 汉字：每个算1字
    - 英文单词：按完整单词计算，撇号作为单词的一部分
    - 数字：每4位算1字，不足4位按1字计算
    - 标点符号：按未被其他类别统计的字符计算
    """
    # 统计汉字（中文字符）
    chinese_words = re.findall(r"[\u4e00-\u9fa5]", text)

    # 统计英文单词（改进的模式，处理中英文混合情况和撇号）
    # 支持撇号作为单词的一部分，如 Hua's, don't 等
    english_words = re.findall(
        r"(?<![a-zA-Z])[a-zA-Z]+(?:'[a-zA-Z]+)*(?![a-zA-Z])", text
    )

    # 先移除已经统计的汉字、英文字母和数字，然后统计剩余的标点符号
    # 创建一个临时文本，移除已经统计的内容
    temp_text = text
    # 移除汉字
    temp_text = re.sub(r"[\u4e00-\u9fa5]", "", temp_text)
    # 移除英文单词（包括带撇号的单词）
    temp_text = re.sub(r"[a-zA-Z]+(?:'[a-zA-Z]+)*", "", temp_text)
    # 移除数字
    temp_text = re.sub(r"\d", "", temp_text)
    # 移除空白字符
    temp_text = re.sub(r"\s", "", temp_text)
    # 剩下的就是标点符号和特殊字符
    punctuations = list(temp_text)

    # 统计数字，每个数字序列（可能包含小数点）计为1个字
    digits = re.findall(r"\d+(?:\.\d+)?", text)
    digit_words = len(digits)

    return len(chinese_words) + len(english_words) + len(punctuations) + digit_words


def _count_words_word_compatible(text: str) -> int:
    """
    Word兼容模式字数统计，适用于学术文献
    
    规则：
    - 汉字：每个算1字
    - 英文字母：每个算1字
    - 特殊数字格式：整个算1字
    - 标点符号：每个算1字，但排除格式化标点
    - 成对符号：开闭符号算2字
    """
    count = 0
    i = 0
    
    while i < len(text):
        char = text[i]
        
        # 处理汉字
        if '\u4e00' <= char <= '\u9fa5':
            count += 1
            i += 1
        # 处理英文字母
        elif char.isalpha():
            count += 1
            i += 1
        # 处理特殊数字格式
        elif char.isdigit() or char == '[':
            # 检查各种特殊数字格式
            special_format = _check_special_number_format(text, i)
            if special_format:
                count += 1
                i += special_format['length']
            else:
                # 普通数字，4位年份特殊处理
                if char.isdigit():
                    # 检查是否为4位年份
                    if i + 3 < len(text) and text[i:i+4].isdigit():
                        year = int(text[i:i+4])
                        if 1000 <= year <= 9999:
                            count += 1
                            i += 4
                        else:
                            count += 1
                            i += 1
                    else:
                        count += 1
                        i += 1
                else:
                    count += 1
                    i += 1
        # 处理标点符号（排除格式化标点）
        elif char not in ' \t\n\r,.:;':
            count += 1
            i += 1
        else:
            i += 1
    
    return count


def _check_special_number_format(text: str, start_pos: int) -> Dict[str, Any]:
    """
    检查特殊数字格式
    
    Returns:
        dict: 包含匹配信息的字典，如果没有匹配返回None
    """
    remaining_text = text[start_pos:]
    
    # 方括号数字格式：[数字]
    match = re.match(r'\[(\d+)\]', remaining_text)
    if match:
        return {'type': 'bracket_number', 'length': len(match.group(0))}
    
    # 圆括号数字格式：(数字)
    match = re.match(r'\((\d+)\)', remaining_text)
    if match:
        return {'type': 'paren_number', 'length': len(match.group(0))}
    
    # 数字范围格式：数字-数字
    match = re.match(r'(\d+)-(\d+)', remaining_text)
    if match:
        return {'type': 'number_range', 'length': len(match.group(0))}
    
    # 小数格式
    match = re.match(r'\d+\.\d+', remaining_text)
    if match:
        return {'type': 'decimal', 'length': len(match.group(0))}
    
    # 百分数格式
    match = re.match(r'\d+(?:\.\d+)?%', remaining_text)
    if match:
        return {'type': 'percentage', 'length': len(match.group(0))}
    
    # 分数格式
    match = re.match(r'\d+/\d+', remaining_text)
    if match:
        return {'type': 'fraction', 'length': len(match.group(0))}
    
    # 对比格式：数字>数字, 数字<数字, 数字=数字
    match = re.match(r'\d+[><=/]\d+', remaining_text)
    if match:
        return {'type': 'comparison', 'length': len(match.group(0))}
    
    return None


def _count_special_numbers(text: str) -> int:
    """
    统计Word兼容模式中的特殊数字格式数量
    """
    count = 0
    i = 0
    
    while i < len(text):
        # 检查特殊数字格式
        special_format = _check_special_number_format(text, i)
        if special_format:
            count += 1
            i += special_format['length']
        elif text[i].isdigit():
            # 检查4位年份
            if i + 3 < len(text) and text[i:i+4].isdigit():
                year = int(text[i:i+4])
                if 1000 <= year <= 9999:
                    count += 1
                    i += 4
                else:
                    i += 1
            else:
                i += 1
        else:
            i += 1
    
    return count
